package com.jasonm.rssminer.dao;

import java.io.IOException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jasonm.rssminer.dto.FeedDTO;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class RssFeedDAO {

	public List<FeedDTO> getFeedContents(String feedName) {
		Logger log = LoggerFactory.getLogger(RssFeedDAO.class);
		List<FeedDTO> feeds = null;
		XmlReader reader = null;
		try {
			URL url = new URL(feedName);

			reader = new XmlReader(url);
			SyndFeed feed = new SyndFeedInput().build(reader);
			if(log.isDebugEnabled())
				log.debug("Feed Title: " + feed.getAuthor());

			feeds = mapToFeedDTO(feed);

		} catch (MalformedURLException badUrl) {
			log.error("Problem with URL:" + badUrl.getMessage());
		} catch (IOException io) {
			log.error("Error parse URL:" + io.getMessage());
		} catch (IllegalArgumentException e) {
			log.error("Some issue parsing the feed:" + e.getMessage());
		} catch (FeedException e) {
			log.error("Feed can't be parsed:" + e.getMessage());
		} finally {
			if (reader != null)
				try {
					reader.close();
				} catch (IOException e) {
					log.error("Can not close reader...so what!");
				}
		}

		return feeds;
	}

	private List<FeedDTO> mapToFeedDTO(SyndFeed syndFeed) {
		List<FeedDTO> feeds = new ArrayList<FeedDTO>();

		for (@SuppressWarnings("unchecked")
		Iterator<SyndEntry> i = syndFeed.getEntries().iterator(); i.hasNext();) {
			SyndEntry entry = i.next();
			feeds.add(new FeedDTO(generateMD5(entry.getTitle()), entry
					.getTitle(), entry.getDescription().getValue(), entry
					.getLink(), entry.getPublishedDate()));

		}
		return feeds;
	}

	private String generateMD5(String input) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] messageDigest = md.digest(input.getBytes());
			BigInteger number = new BigInteger(1, messageDigest);
			String hashtext = number.toString(16);
			// Now we need to zero pad it if you actually want the full 32
			// chars.
			while (hashtext.length() < 32) {
				hashtext = "0" + hashtext;
			}
			return hashtext;
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}

	}

}
